package org.raccoon.sequence.core.pool;

import org.raccoon.sequence.core.factory.SequenceFactoryImpl;
import java.util.*;

/**
 * Sequence 资 源 池 -- [就眠仪式]
 * */
public class SequencePool {

    /**
     * 初 始 化 配 置 信 息
     * */
    private SequencePoolConfig config;

    /**
     * 可 用 空 闲 的 Id 序 列 号
     * */
    private Queue<Long> queue = new LinkedList<Long>();


    /**
     * 初 始 化 配 置 信 息
     * */
    public SequencePool(SequencePoolConfig config){

        this.config = config;

    }

    /**
     * 初 始 化 ID 资 源 池
     * */
    public void init(){

        Set<Long> ids = SequenceFactoryImpl.getInstance(config.getWorkerId(),config.getCenterId()).makeId(config.getInitSize());

        ids.forEach(item->{

            queue.offer(item);

        });

    }

    /**
     * 获 取 队 列 中 的 Id
     * */
    public Long getId(){

        long id = queue.poll();

        return id;
    }

    /**
     * 获 取 队 列 中 的 Id
     * */
    public List<Long> getId(int batchSize){

        isEnough(batchSize);

        List<Long> ids = new ArrayList<>();

        for (int current = 0; current < batchSize; current++){

            ids.add(queue.poll());
        }

        isEnough(config.getMinIdle());

        return ids;
    }

    /**
     * Id 数 量 是 否 满 足 配 置
     * */
    public void isEnough(int batchSize){

        int genSize = batchSize - queue.size();

        if(batchSize > queue.size()){

            Set<Long> ids = SequenceFactoryImpl.getInstance(config.getWorkerId(),config.getCenterId()).makeId(genSize);

            ids.forEach(id->{

                queue.offer(id);

            });

        }
    }

    /**
     * 获 取 当 前可 用 的 Id
     * */
    public int getCount(){

        return queue.size();

    }

    /**
     * 获 取 当 前 资 源 池 的 配 置 信 息
     * */
    public SequencePoolConfig getConfig(){

        return config;
    }

}
